import socket, sys, time

# 检查命令行参数数量是否足够
if len(sys.argv) != 4:
    print("Usage: python shutdown.py <host> <textport> <filename>")
    print("Example: python shutdown.py example.com 80 index.html")
    sys.exit(1)

host = sys.argv[1]
textport = sys.argv[2]
filename = sys.argv[3]

try:
    # 尝试创建一个基于 IPv4 地址族和 TCP 协议的套接字
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
    # socket.error 异常：在创建套接字过程中出现未知错误时触发
    print('Strange error creating socket')
    sys.exit(1)

try:
    # 尝试将传入的端口号从字符串转换为整数
    port = int(textport)
except ValueError:
    # ValueError 异常：当传入的端口号不是有效的整数格式时触发
    try:
        # 若端口号不是整数，尝试根据服务名获取对应的端口号
        port = socket.getservbyname(textport, 'tcp')
    except socket.error:
        # socket.error 异常：在根据服务名获取端口号失败时触发
        print("Couldn't find your port")
        sys.exit(1)

try:
    # 尝试连接到指定的主机和端口
    s.connect((host,port))
except socket.gaierror:
    # socket.gaierror 异常：在地址解析相关操作失败时触发，如域名解析失败
    print('Addresss-related error connecting to server')
    sys.exit(1)
except socket.error:
    # socket.error 异常：在连接服务器过程中出现其他错误时触发
    print('Connecting error')
    sys.exit(1)

print('sleeping...')
time.sleep(10)
print('Continuing')

try:
    # 将字符串转换为字节类型，使用 UTF-8 编码并发送请求
    s.sendall(('GET %s HTTP/1.0\r\n\r\n' % filename).encode('utf-8'))
except socket.error:
    # socket.error 异常：在发送数据过程中出现错误时触发
    print('Error sending data')
    sys.exit(1)

try:
    # 关闭套接字的写端，仅保留读端
    s.shutdown(1)
except socket.error:
    # socket.error 异常：在关闭套接字写端操作失败时触发
    print("Error sending data")
    sys.exit(1)

while True:
    try:
        # 从套接字接收最多 2048 字节的数据
        buf = s.recv(2048)
    except socket.error:
        # socket.error 异常：在接收数据过程中出现错误时触发
        print('Error receving data')
        sys.exit(1)
    if not len(buf):
        break
    # 将接收到的字节数据转换为字符串并打印
    sys.stdout.write(buf.decode('utf-8', errors='ignore'))    